import {Canvas, Meta, Story} from '@storybook/blocks'

import * as SelectMenuStories from './SelectMenu.stories'

<Meta of={SelectMenuStories} />

# SelectMenu

Please note that this is a newer version and uses the `.SelectMenu` class instead of the <a href="/css/components/select-menu-deprecated">deprecated select menu</a> class. Check the <a href="/css/components/select-menu-deprecated">migration guide</a> to make sure your app is up to date.

The `SelectMenu` component provides advanced support for navigation, filtering, and more. Any menu can make use of JavaScript-enabled live filtering, selected states, tabbed lists, and keyboard navigation with a bit of markup.

## Basic example

Use a `<details>` element to toggle the select menu. The `<summary>` element can be styled in many ways. In the example below it's a `.btn`.

<Canvas of={SelectMenuStories.Default} />

Add a `.SelectMenu-header` to house a clear title and a close button. Note that the close button is only shown on narrow screens (mobile).

## Right aligned

In case the select menu should be aligned to the right, use `SelectMenu right-0`.

<Canvas of={SelectMenuStories.RightAligned} />

## Selected state

If the `SelectMenu` should show a check icon for selected items, use the `SelectMenu-icon SelectMenu-icon--check` classes. It will make the check icon show when `aria-checked="true"` is set.

<Canvas of={SelectMenuStories.SelectedState} />

## Borderless

Use the `.SelectMenu-list--borderless` modifier to remove the borders between list items. Note: It's better to keep the borders if a list contains items with multiple lines of text. It will make it easier to see where the items start and end.

<Canvas of={SelectMenuStories.Borderless} />

## Header

Add a `.SelectMenu-header` at the top to house a clear title and a close button.

<Canvas of={SelectMenuStories.Header} />

## List items

The list of items is arguably the most important subcomponent within the menu. Build them out of anchors, buttons, or just about any [interactive content](http://w3c.github.io/html/dom.html#interactive-content). List items are also customizable with options for avatars, additional icons, and multiple lines of text. Use utility classes in case more custom styling is needed.

<Canvas of={SelectMenuStories.ListItems} />

## Divider

The select menu's list can be divided into multiple parts by adding a `.SelectMenu-divider`. It can be a `<div>` with text/content. Or just an `<hr>` to add a visual separator.

Dividers are also supported when using the `.SelectMenu-list--borderless` modifier.

<Canvas of={SelectMenuStories.Divider} />

## Footer

Use a `.SelectMenu-footer` at the bottom for additional information. As a side effect it can greatly improve the scrolling performance because the list doesn't need to be repainted due to the rounded corners.

<Canvas of={SelectMenuStories.Footer} />

## Filter

If the list is expected to get long, consider adding a `.SelectMenu-filter` input. Be sure to also include the `.SelectMenu--hasFilter` modifier class. On mobile devices it will add a fixed height and anchor the select menu to the top of the screen. This makes sure the filter input stays at the same position while typing.

<Canvas of={SelectMenuStories.Filter} />

## Tabs

Sometimes you need two or more lists of items in your select menu, e.g. branches and tags. Select menu lists can be tabbed with the addition of `.SelectMenu-tabs` above the menu.

<Canvas of={SelectMenuStories.Tabs} />

## Message

A `SelectMenu-message` can be used to show different kind of messages to a user. Use utility classes to further style the message.

<Canvas of={SelectMenuStories.Message} />

## Loading

When fetching large lists, consider showing a `.SelectMenu-loading` animation.

<Canvas of={SelectMenuStories.Loading} />

## Disabled

To disable a list item, use the `disabled` attribute for `<button>`s. For `<a>`s replace the `href` with an `aria-disabled="true"` attribute. Note: If not obvious, try to communicate to the user why an item is disabled.

<Canvas of={SelectMenuStories.Disabled} />

## Blankslate

Sometimes a select menu needs to communicate a "blank slate" where there's no content in the menu's list. Usually these include a clear call to action to add said content to the list. Swap out the contents of a `.SelectMenu-list` with a `.SelectMenu-blankslate` and customize its contents as needed.

<Canvas of={SelectMenuStories.BlankSlate} />

## github.com usage

When adding the `.SelectMenu` component on github.com, use the [`<details-menu>`](https://github.com/github/details-menu-element) element. It will magically make the `.SelectMenu` work. Here a basic example:

```erb
<details class="details-reset details-overlay" id="my-select-menu">
  <summary class="btn">
    <span>Choose</span>
    <span class="dropdown-caret"></span>
  </summary>
  <details-menu class="SelectMenu" role="menu">
    <div class="SelectMenu-modal">
      <header class="SelectMenu-header">
        <span class="SelectMenu-title">My Select Menu</span>
        <button class="SelectMenu-closeButton" type="button" data-toggle-for="my-select-menu">
          <%= octicon("x", "aria-label": "Close menu") %>
        </button>
      </header>
      <div class="SelectMenu-list">
        <a class="SelectMenu-item" href="" role="menuitem">Item 1</a>
        <a class="SelectMenu-item" href="" role="menuitem">Item 2</a>
        <a class="SelectMenu-item" href="" role="menuitem">Item 3</a>
      </div>
    </div>
  </details-menu>
</details>
```

If loading content should be deferred, use the [`<include-fragment>`](https://github.com/github/details-menu-element) element:

```erb
<details-menu class="SelectMenu" src="/my-menu" preload>
  <div class="SelectMenu-modal">
    <include-fragment class="SelectMenu-loading" aria-label="Menu is loading">
      <%= octicon("octoface", class: "anim-pulse", :height => 32) %>
    </include-fragment>
  </div>
</details-menu>
```

It will add a pulsing "octoface" icon while the content is loading.
